﻿' Licensed under GNU General Public License version 2 (GPLv2) 
' Copyright (C) 1989, 1991 Free Software Foundation, Inc.
'
' Everyone is permitted to copy and distribute verbatim copies
' of this license document, but changing it is not allowed.

Imports System.Net

Module Module1

#Region "Main methods"
    ''' <summary>
    ''' Main function of class.
    ''' </summary>
    ''' <param name="args">Arguments for the console application.</param>
    ''' <remarks></remarks>
    Sub Main(ByVal args As String())
        Dim pingCount As Integer = 4

        Console.WriteLine()

        Select Case (args.Length)
            Case 0
                ShowHelp()
            Case Else
                Dim commandLine As Arguments = New Arguments(args)
                Dim strHost As String = args(0)
                Dim strUser As String = String.Empty
                Dim strPassword As String = String.Empty

                ' build correct URL
                If Not strHost.StartsWith("http") Then
                    strHost = "http://" & strHost
                End If

                ' switch command lines
                If Not commandLine("u") Is Nothing Then
                    strUser = commandLine("u")
                End If
                If Not commandLine("p") Is Nothing Then
                    strUser = commandLine("p")
                End If
                If Not commandLine("n") Is Nothing Then
                    pingCount = commandLine("n")
                End If

                ' do the ping
                Dim nList As NumberList = New NumberList

                Console.WriteLine("Pinging " & strHost & " " & pingCount.ToString & " times:")
                For i As Integer = 1 To pingCount
                    nList.Add(PingHttpHost(strHost, strUser, strPassword))
                Next

                Console.WriteLine()
                Console.WriteLine("Approximate round trip times in milli-seconds:")
                Console.WriteLine(" Minimum: " & nList.Minimum & "ms, Maximum: " & nList.Maximum & "ms, Average: " & nList.Average & "ms")
                Console.WriteLine()
        End Select

        'Console.ReadLine()
    End Sub
#End Region

#Region "Private Methods"
    ''' <summary>
    ''' Conducts a http web request to the page to measure success and RTT.
    ''' </summary>
    ''' <param name="host">URL of host to ping.</param>
    ''' <param name="user">Username if authentication is needed, requires password to be specified.</param>
    ''' <param name="password">Password if authentication is needed, requires username to be specified.</param>
    ''' <returns>Returns roundtrip time.</returns>
    ''' <remarks></remarks>
    Private Function PingHttpHost(ByVal host As String, ByVal user As String, ByVal password As String) As Integer
        ' timers
        Dim requestStart As DateTime = DateTime.Now
        Dim requestTime As Integer

        ' create request
        Dim request As HttpWebRequest = HttpWebRequest.Create(host)
        request.Method = "GET"
        request.Timeout = 30000
        request.UserAgent = "httpping/v1"
        request.AllowAutoRedirect = True
        request.MaximumAutomaticRedirections = 5

        ' set authenticatino level
        If user <> String.Empty AndAlso password <> String.Empty Then
            request.Credentials = New NetworkCredential(user, password)
        End If

        Try
            Dim response As HttpWebResponse = CType(request.GetResponse, HttpWebResponse)
            Dim requestEnd As DateTime = DateTime.Now
            requestTime = requestEnd.Subtract(requestStart).Milliseconds

            Console.WriteLine(" Reply with status-code: " & response.StatusCode & " time=" & requestTime & "ms, content-length=" & response.ContentLength)

            response.Close()
        Catch ex As TimeoutException
            Console.WriteLine(" Timeout for: " & host)
        Catch ex As Sockets.SocketException
            Console.WriteLine(" SocketException for: " & host)
        Catch ex As UnauthorizedAccessException
            Console.WriteLine(" Unauthorized to access: " & host)
        Catch ex As WebException
            Console.WriteLine(" Unable to connect to: " & host)
            'Throw ex
        Catch ex As Exception
            Console.WriteLine(" Unknown error: " & host)
            'Throw ex
        End Try

        Return requestTime
    End Function

    ''' <summary>
    ''' Displays help for the command line tool.
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub ShowHelp()
        Console.WriteLine("Usage: httpping target_url [-u username] [-p password] [-t timeout] [-n count]")
        Console.WriteLine()
        Console.WriteLine("Options:")
        Console.WriteLine(vbTab & "-u" & vbTab & vbTab & "Specify username to authenticate.")
        Console.WriteLine(vbTab & vbTab & vbTab & "Required password as well.")
        Console.WriteLine(vbTab & "-p" & vbTab & vbTab & "Specify password to authenticate.")
        Console.WriteLine(vbTab & vbTab & vbTab & "Required username as well.")
        Console.WriteLine(vbTab & "-t" & vbTab & vbTab & "Specify timeout in milliseconds.")
        Console.WriteLine(vbTab & "-n" & vbTab & vbTab & "Number of requests to send. Default = 4.")
        Console.WriteLine()
    End Sub
#End Region
End Module
